package com.itmsoft.test.utils.java;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.spi.ObjectFactory;

import com.itmsoft.util.Constants;

import org.apache.commons.lang3.StringUtils;

/**
 * Open EJB doesn't publishes resources (jms and jdbc) into jndi space. To work
 * this around I've came up with solution to route back from Object factory to
 * open ejb with resource prepender.
 * 
 * System property is set: Context.URL_PKG_PREFIXES to "package" so that open
 * ejb will federate search to this context factory.
 * 
 * Only Constants.Jndi.JNDI_PREPENDER names are rerouted not to create circular
 * references and
 * correctly handle resource names.
 */
public class javaURLContextFactory implements ObjectFactory
{
    private static final String TRAINEE_SERVICES = "/" + Constants.TRAINEE_SURNAME
    + "-services/";
    private InitialContext ctx;
    {
        try
        {
            ctx = new InitialContext();
        }
        catch (NamingException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment)
        throws Exception
    {
        String stringName = name != null ? name.toString() : null;
        if (stringName != null && stringName.contains(Constants.TRAINEE_SURNAME + "-ear"))
        {
            try
            {
                return ctx.lookup("java:/"
                    + StringUtils
                        .replaceOnce(stringName, Constants.TRAINEE_SURNAME + "-ear", "classpath.ear"));
            }
            catch (NamingException e)
            {
                // since maven includes norris-services.jar OpenEjb names module
                // as norris-services which is different from the services
                // module id when working with simple eclipse or weblogic or
                // jboss. Will just look up with replacement "norris-services"
                // instead of "/services/"
                return ctx.lookup("java:/"
                    + StringUtils.replaceOnce(StringUtils.replaceOnce(stringName, Constants.TRAINEE_SURNAME
                        + "-ear", "classpath.ear"), "/services/", TRAINEE_SERVICES));
            }
        }
        if (stringName != null && !stringName.contains("Resource/")
            && (stringName.contains(Constants.Jndi.JNDI_PREPENDER)))
        {
            return ctx.lookup("openejb:Resource/" + stringName);
        }
        return null;
    }
}
